<?php

class Dispatch {

  private static $_instance;

  private function __construct() {
    
  }
  
  public static function getRoutes() {
    Route::add('admin', 'admin/:module/:controller/:action/*', array(
                'is_admin' => true,
                'module' => 'manage',
                'controller' => 'index',
                'action' => 'index',
            ));
    Route::add('default', ':module/:component/:controller/:action/*', array(
                'module' => 'welcome',
                'component' => 'index',
                'controller' => 'index',
                'action' => 'index',
            ));
    Route::add('default', ':module/:controller/:action/*', array(
                'module' => 'welcome',
                'controller' => 'index',
                'action' => 'index',
            ));
    return Route::all();
  }

  /**
   * @param  array  $params array('module','is_admin','component','controller','action')
   * @return array  ($class_name, $action_name)  SUCCESS
   * @return FALSE  FAILURE
   */
  public static function check($params) {
    $parts = array(self::inflect(@$params['module']), 'Controller');
    if (@$params['is_admin']) {
      $parts[] = 'Admin';
    }
    if (@$params['component']) {
      $parts[] = self::inflect($params['component']);
    }
    if (@$params['controller']) {
      $parts[] = self::inflect($params['controller']);
    }

    if (!file_exists($filename = PACKAGE_DIR . implode(DIRECTORY_SEPARATOR, $parts) . '.php')) {
      return false;
    }

    require_once $filename;
    $class_name = implode('_', $parts);

    if (class_exists($class_name) && ($action = @$params['action']) && method_exists($class_name, $action . 'Action')) {
      return array($class_name, $action);
    }
    return false;
  }

  /**
   *
   * @param   string  $name
   * @return  string
   */
  public static function inflect($name) {
    return str_replace(' ', '', ucwords(str_replace(array('.', '-'), ' ' , $name)));
  }
  
  public static function deflect($name){
    return strtolower(trim(preg_replace('/([a-z0-9])([A-Z])/', '\1-\2', $name), '-. '));
  }

  /**
   *
   */
  public static function execute() {
    $uri = isset($_SERVER['REQUEST_URI'])?$_SERVER['REQUEST_URI']:'/';
    
    
    $uri = str_replace(BASE_URL, '', $uri);
    
    $flag = false;
    $con = NULL;
    
    foreach (self::getRoutes() as $route) {
      if ($params = $route->match($uri)) {
        if ($parts = Dispatch::check($params)) {
          $flag = true;
          list($class_name, $action) = $parts;
          $con = Controller::factory($class_name, $params);
          $con->forward($action);
          break;
        }
      }
    }
    if ($flag == false) {
      $flag = true;
      $params = array('module'=>'welcome','controller'=>'index','action'=>'pageNotFound');
      list($class_name, $action) = array('Welcome_Controller_Index','pageNotFound');
      $con = Controller::factory($class_name, $params);
      $con->forward($action);
    }
  }  

}